package user;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.sql.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import config.redisConfig;
import redis.clients.jedis.Jedis;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import util.DBUtil;
import java.util.HashMap;

import static java.lang.System.out;

@WebServlet("/userLoginServlet")  
public class userLoginServlet extends HttpServlet {
    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json");
        resp.setCharacterEncoding("UTF-8");

        String action = req.getParameter("action");


        Map<String, Object> response = new HashMap<>();

        if (action == null || action.trim().isEmpty()) {
            response.put("status", "error");
            response.put("message", "缺少action参数");
            resp.getWriter().write(mapper.writeValueAsString(response));
            return;
        }

        try {
            if ("userLogin".equals(action)) {
                String userName = req.getParameter("userName");
                String passWord = req.getParameter("passWord");

                // 验证参数
                if (userName == null || userName.trim().isEmpty() ||
                        passWord == null || passWord.trim().isEmpty()) {
                    response.put("status", "error");
                    response.put("message", "用户名和密码不能为空");
                    resp.getWriter().write(mapper.writeValueAsString(response));
                    return;
                }

                try (Connection connection = DBUtil.getConnection()) {
                    String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
                    try (PreparedStatement stmt = connection.prepareStatement(sql)) {
                        stmt.setString(1, userName);
                        stmt.setString(2, passWord);

                        try (ResultSet resultSet = stmt.executeQuery()) {
                            if (resultSet.next()) {
                                // 登录成功
                                HttpSession session = req.getSession();
                                session.setAttribute("username", userName);
                                session.setAttribute("userType", "user");
                                session.setAttribute("userId", resultSet.getInt("id"));
                                session.setAttribute("userAvatarUrl", resultSet.getString("avatar_url"));

                                // 取出原来请求的页面
                                String redirectURL = (String) session.getAttribute("redirectAfterLogin");

                                if (redirectURL != null) {
                                    resp.sendRedirect(redirectURL);  // 回到原来的页面
                                    session.removeAttribute("redirectAfterLogin"); // 避免后续重复跳转
                                    out.print(mapper.writeValueAsString(Map.of(
                                            "status", "success"
                                    )));
                                } else {
                                    response.put("status", "success");
                                    response.put("redirectUrl", "/user/owner.jsp");
                                }
                            } else {
                                response.put("status", "error");
                                response.put("message", "用户名或密码错误");
                            }
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                    response.put("status", "error");
                    response.put("message", "数据库错误: " + e.getMessage());
                }
            }
            else if("userRegister".equals(action)){
                userRegister(req,resp);
            }else if("userSendEmail".equals(action)){
                userSendEmailCode(req,resp);
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.put("status", "error");
            response.put("message", "服务器错误: " + e.getMessage());
        }

        resp.getWriter().write(mapper.writeValueAsString(response));
    }

    /**
     * 用户退出登录
     * @param req
     * @param resp
     */
    private void userLoginOut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        HttpSession session = req.getSession(false);
        if (session != null) {
            session.invalidate();
        }
        
        Map<String, String> response = new HashMap<>();
        response.put("status", "success");
        response.put("message", "已成功退出登录");
        resp.getWriter().write(mapper.writeValueAsString(response));
    }

    /**
     * 用户注册
     */
    private void userRegister(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String userName = req.getParameter("userName");
        String passWord = req.getParameter("passWord");

        try (Connection connection =  DBUtil.getConnection()) {
            String checkSql = "SELECT * FROM users WHERE username = ?";
            try (PreparedStatement checkStmt = connection.prepareStatement(checkSql)) {
                checkStmt.setString(1, userName);
                try (ResultSet checkResult = checkStmt.executeQuery()) {
                    if (checkResult.next()) {
                        resp.setStatus(HttpServletResponse.SC_CONFLICT);
                        resp.getWriter().write("{\"message\": \"用户名已存在！\"}");
                        return;
                    }
                }
            }

            String insertSql = "INSERT INTO users (username, password) VALUES (?, ?)";
            try (PreparedStatement insertStmt = connection.prepareStatement(insertSql)) {
                insertStmt.setString(1, userName);
                insertStmt.setString(2, passWord);
                int rowsAffected = insertStmt.executeUpdate(); //数库更新之后受影响的行数，大于0就说明数据更新成功
                if (rowsAffected > 0) {
                    resp.setStatus(HttpServletResponse.SC_OK);
                    resp.getWriter().write("{\"message\": \"注册成功！\"}");
                    resp.sendRedirect("./login.jsp");
                } else {
                    resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    resp.getWriter().write("{\"message\": \"注册失败，请稍后再试！\"}");
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    /*
    用户注册时发送的邮箱验证码
     */
    private void userSendEmailCode(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json");

        String email = req.getParameter("email");
        String code = generateCode();

        try {
            sendEmail(email, code);
            storeCodeInRedis(email, code);
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.getWriter().write("{\"message\": \"验证码发送成功！\"}");
        } catch (Exception e) {
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.getWriter().write("{\"message\": \"发送验证码失败，请稍后再试！\"}");
        }
    }

    private String generateCode() {
        Random random = new Random();
        int code = 100000 + random.nextInt(900000);
        return String.valueOf(code);
    }

    private void sendEmail(String to, String code) throws MessagingException {
        final String from = "3494123439@qq.com";
        final String host = "smtp.qq.com";
        final String password = "hmgglrkptoozdbhd";  //授权码

        Properties properties = System.getProperties();
        properties.setProperty("mail.smtp.host", host);
        properties.setProperty("mail.smtp.port", "587");
        properties.setProperty("mail.smtp.auth", "true");
        properties.setProperty("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(from, password);
            }
        });

        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
        message.setSubject("您的验证码");
        message.setText("您的验证码是：" + code);
        Transport.send(message);
    }

    private void storeCodeInRedis(String email, String code) {
        try (Jedis jedis = redisConfig.getPool().getResource()) {
            jedis.setex(email, 300, code); // 300秒（5分钟）过期
        }
    }

    private void sendErrorResponse(HttpServletResponse resp, String message) throws IOException {
        Map<String, String> response = new HashMap<>();
        response.put("status", "fail");
        response.put("message", message);
        resp.getWriter().write(mapper.writeValueAsString(response));
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}
